package com.idanchuang.component.mybatis.plus;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.idanchuang.component.core.helper.ConfigPressureMybatisPlusInterceptor;
import com.idanchuang.component.mybatis.plus.config.MybatisConfigBean;
import com.idanchuang.component.mybatis.plus.plugins.AvailableSqlParser;
import com.idanchuang.component.mybatis.plus.plugins.PressureTableNameParser;
import com.idanchuang.component.mybatis.plus.plugins.ProcessTimeInterceptor;
import com.idanchuang.component.mybatis.plus.plugins.QueryLimitSqlParser;
import com.idanchuang.component.mybatis.plus.plugins.ShadowSQLRewriteParser;
import com.idanchuang.support.mybatis.crypt.CryptInterceptor;
import com.idanchuang.support.mybatis.crypt.config.CryptConfigBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Configuration for Mybatis-plus
 *
 * @author yjy
 * @author Raistlin
 * @date 2019/12/4 16:31
 **/
@Configuration
public class ComponentMybatisPlusPureAutoConfiguration {

    /**
     * Mybatis-plus Sql Parsers
     */
    @Autowired
    private List<AvailableSqlParser> parsers;

    /**
     * Mybatis-plus Pagination Interceptor
     */
    @Bean
    @ConditionalOnMissingBean(PaginationInterceptor.class)
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    /**
     * Default Configurations
     *
     * @return
     */
    @Bean
    @ConfigurationProperties("idanchuang.component.mybatisplus")
    public MybatisConfigBean mybatisConfigBean() {
        return new MybatisConfigBean();
    }

    /**
     * Process Time Interceptor
     *
     * @param mybatisConfigBean
     * @return
     */
    @Bean
    @ConditionalOnBean(MybatisConfigBean.class)
    public ProcessTimeInterceptor processTimeInterceptor(MybatisConfigBean mybatisConfigBean) {
        return new ProcessTimeInterceptor(mybatisConfigBean);
    }

    /**
     * Crypt Configurations
     *
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "mysql.encryptor")
    public CryptConfigBean cryptConfigBean() {
        return new CryptConfigBean();
    }

    /**
     * Crypt Interceptor
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(CryptInterceptor.class)
    public CryptInterceptor cryptInterceptor() {
        return new CryptInterceptor();
    }

    /**
     * Shadow Table Parser
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(name = "acgPressureTableNameParser")
    public PressureTableNameParser acgPressureTableNameParser() {
        return new PressureTableNameParser();
    }

    /**
     * Query Limitation Parser
     *
     * @param mybatisConfigBean
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(name = "acgQueryLimitSqlParser")
    public QueryLimitSqlParser acgQueryLimitSqlParser(MybatisConfigBean mybatisConfigBean) {
        return new QueryLimitSqlParser(mybatisConfigBean);
    }

    /**
     * Shadow SQL Rewrite Parser
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(name = "acgShadowRewriteParser")
    public ShadowSQLRewriteParser acgShadowRewriteParser(){
        return new ShadowSQLRewriteParser();
    }

    @Bean
    @ConditionalOnMissingBean(ConfigPressureMybatisPlusInterceptor.class)
    public ConfigPressureMybatisPlusInterceptor configPressureMybatisPlusInterceptor(PaginationInterceptor paginationInterceptor) {
        if (paginationInterceptor.getSqlParserList() == null) {
            paginationInterceptor.setSqlParserList(new ArrayList<>());
        }
        if (!CollectionUtils.isEmpty(parsers)) {// add parsers if non-null
            paginationInterceptor.getSqlParserList().addAll(parsers);
        }
        return new ConfigPressureMybatisPlusInterceptor();
    }

}
